#ifndef _SATA_H
#define _SATA_H

#include <hal/ahci/hba.h>

#define SATA_REG_FIS_D2H 0x34
#define SATA_REG_FIS_H2D 0x27
#define SATA_REG_FIS_COMMAND 0x80
#define SATA_LBA_COMPONENT(lba, offset) ((((lba) >> (offset)) & 0xff))

#define ATA_IDENTIFY_DEVICE 0xEC
#define ATA_IDENTIFY_PAKCET_DEVICE 0xA1
#define ATA_PACKET 0xA0
#define ATA_READ_DMA_EXT 0x25
#define ATA_READ_DMA 0xC8
#define ATA_WRITE_DMA_EXT 0x35
#define ATA_WRITE_DMA 0xCA

#define MAX_RETRY 2

typedef struct sata_fis_head {
    u8 type;
    u8 options;
    u8 status_cmd;
    u8 feat_err;
} packed sata_fish_t;

typedef struct sata_cmd_fis {
    sata_fish_t head;

    u8 lba0, lba8, lba16;
    u8 dev;
    u8 lba24, lba32, lba40;
    u8 feature;

    u16 count;

    u8 reserved[6];
} packed sata_cmd_fis_t;

typedef struct sata_data_fis {
    sata_fish_t head;
    u8 data[0];
} packed sata_data_fis_t;

void sata_create_fis(sata_cmd_fis_t* cmd_fis, u8 command, u64 lba, u16 sector_count);

void sata_submit(hba_dev_t* dev, blkio_req_t* req);

void sata_read_error(hba_port_t* port);

#endif /* _SATA_H */